package com.titaniume.java1;

import java.util.concurrent.locks.ReentrantLock;

/**
 *@program: JavaSenior
 *@description: 解决线程安全问题方式三： Lock锁  JDK5.0新增
 *
 *
 *
 * //面试题 synchronized 与 Lock二 异同
 *  相同: 二者都可以解决线程安全问题
 *  不同: sychronized 机制在执行完相对于的同步代码块以后，自动的释放同步监视器
 *    Lock需要手动开启同步（lock()） ，同时结束同步也需要手动实现（unlock()）
 *
 *
 * 面试题： 如何解决线程安全同步问题？有几种
 *  1.synchronized 同步代码块
 *  2.synchronized 同步方法
 *  3.Lock
 *
 *
 *
 *
 *@author: renfei.huang
 *@create: 2021-09-30 08:49
 */
public class LockTest {
    public static void main(String[] args) {

        Window w = new Window();

        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);

        t1.setName("窗口一");
        t2.setName("窗口二");
        t3.setName("窗口三");

        t1.start();
        t2.start();
        t3.start();
    }

}


class Window implements Runnable {

    private int ticket = 100;


    //1.实例化一个 ReentrantLock
    private ReentrantLock lock = new ReentrantLock();


    @Override
    public void run() {

        while (true) {

            try {

                //2.调用锁定的方法lock
                lock.lock();

                if (ticket > 0) {

                    //重票或错票问题出现概率大一些  Thread.sleep(100);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ":票号为:" + ticket);
                    ticket--;
                } else {
                    break;
                }
            } finally {
                //3. 调用解锁的方法
                lock.unlock();
            }

        }
    }
}